<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>4-2 全连接网络演示器</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/Chart.js/4.4.0/chart.min.js"></script>
    <style>
        body {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
        }
        .glass-card {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
    </style>
</head>
<body class="flex items-center justify-center p-4">
    <div class="max-w-4xl w-full">
        <h1 class="text-4xl font-bold text-white text-center mb-8">4-2 全连接网络演示器</h1>
        
        <div class="grid md:grid-cols-2 gap-6">
            <!-- 输入区域 -->
            <div class="glass-card rounded-xl p-6">
                <h2 class="text-2xl font-semibold text-white mb-4">输入层 (4维)</h2>
                <div class="space-y-4">
                    <div>
                        <label class="block text-sm font-medium text-white mb-2">输入1: <span id="value1" class="text-yellow-300">0.0</span></label>
                        <input type="range" id="input1" min="-5" max="5" step="0.1" value="0" 
                               class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label class="block text-sm font-medium text-white mb-2">输入2: <span id="value2" class="text-yellow-300">0.0</span></label>
                        <input type="range" id="input2" min="-5" max="5" step="0.1" value="0" 
                               class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label class="block text-sm font-medium text-white mb-2">输入3: <span id="value3" class="text-yellow-300">0.0</span></label>
                        <input type="range" id="input3" min="-5" max="5" step="0.1" value="0" 
                               class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
                    </div>
                    <div>
                        <label class="block text-sm font-medium text-white mb-2">输入4: <span id="value4" class="text-yellow-300">0.0</span></label>
                        <input type="range" id="input4" min="-5" max="5" step="0.1" value="0" 
                               class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer">
                    </div>
                </div>
                
                <button onclick="resetWeights()" 
                        class="w-full mt-6 bg-red-500 hover:bg-red-600 text-white font-bold py-3 px-4 rounded-lg transition duration-300">
                    🔄 重新随机权重
                </button>
            </div>
            
            <!-- 输出区域 -->
            <div class="glass-card rounded-xl p-6">
                <h2 class="text-2xl font-semibold text-white mb-4">输出层 (2维)</h2>
                <div class="bg-white bg-opacity-10 rounded-lg p-4">
                    <canvas id="outputChart" width="300" height="200"></canvas>
                </div>
                
                <div class="mt-4 text-white">
                    <div class="flex justify-between mb-2">
                        <span>输出1:</span>
                        <span id="output1" class="text-green-300 font-bold">0.000</span>
                    </div>
                    <div class="flex justify-between">
                        <span>输出2:</span>
                        <span id="output2" class="text-green-300 font-bold">0.000</span>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 权重信息 -->
        <div class="glass-card rounded-xl p-6 mt-6">
            <h2 class="text-xl font-semibold text-white mb-3">当前权重信息</h2>
            <div class="text-sm text-gray-300">
                <div id="weightsInfo" class="grid grid-cols-2 gap-4 text-xs">
                    <!-- 权重信息将通过JS动态填充 -->
                </div>
            </div>
        </div>
    </div>

    <script>
        let chart;
        
        // 初始化图表
        function initChart() {
            const ctx = document.getElementById('outputChart').getContext('2d');
            chart = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: ['输出1', '输出2'],
                    datasets: [{
                        label: '输出值',
                        data: [0, 0],
                        backgroundColor: [
                            'rgba(34, 197, 94, 0.8)',
                            'rgba(59, 130, 246, 0.8)'
                        ],
                        borderColor: [
                            'rgba(34, 197, 94, 1)',
                            'rgba(59, 130, 246, 1)'
                        ],
                        borderWidth: 2
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            display: false
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: false,
                            min: -5,
                            max: 5,
                            ticks: {
                                color: 'white'
                            },
                            grid: {
                                color: 'rgba(255, 255, 255, 0.2)'
                            }
                        },
                        x: {
                            ticks: {
                                color: 'white'
                            },
                            grid: {
                                color: 'rgba(255, 255, 255, 0.2)'
                            }
                        }
                    }
                }
            });
        }
        
        // 更新输入值显示
        function updateInputValue(sliderId, valueId) {
            const slider = document.getElementById(sliderId);
            const value = document.getElementById(valueId);
            value.textContent = parseFloat(slider.value).toFixed(1);
            predict();
        }
        
        // 预测函数
        async function predict() {
            const input1 = parseFloat(document.getElementById('input1').value);
            const input2 = parseFloat(document.getElementById('input2').value);
            const input3 = parseFloat(document.getElementById('input3').value);
            const input4 = parseFloat(document.getElementById('input4').value);
            
            try {
                const response = await fetch('http://localhost:5000/predict', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        input: [input1, input2, input3, input4]
                    })
                });
                
                const data = await response.json();
                if (data.error) {
                    console.error('预测错误:', data.error);
                    return;
                }
                
                // 更新输出显示
                document.getElementById('output1').textContent = data.output[0].toFixed(3);
                document.getElementById('output2').textContent = data.output[1].toFixed(3);
                
                // 更新图表
                chart.data.datasets[0].data = data.output;
                chart.update();
                
                // 更新权重信息
                updateWeightsInfo(data.weights, data.bias);
                
            } catch (error) {
                console.error('请求错误:', error);
            }
        }
        
        // 重置权重
        async function resetWeights() {
            try {
                const response = await fetch('http://localhost:5000/reset_weights', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    }
                });
                
                const data = await response.json();
                if (data.error) {
                    console.error('重置错误:', data.error);
                    return;
                }
                
                // 重新预测
                predict();
                
            } catch (error) {
                console.error('重置请求错误:', error);
            }
        }
        
        // 更新权重信息
        function updateWeightsInfo(weights, bias) {
            const weightsInfo = document.getElementById('weightsInfo');
            let html = '';
            
            // 显示权重矩阵
            html += '<div><strong>权重矩阵 (4×2):</strong><br>';
            for (let i = 0; i < 4; i++) {
                html += `[${weights[i][0].toFixed(3)}, ${weights[i][1].toFixed(3)}]<br>`;
            }
            html += '</div>';
            
            // 显示偏置向量
            html += '<div><strong>偏置向量 (2×1):</strong><br>';
            html += `[${bias[0].toFixed(3)}, ${bias[1].toFixed(3)}]`;
            html += '</div>';
            
            weightsInfo.innerHTML = html;
        }
        
        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            initChart();
            
            // 绑定输入事件
            document.getElementById('input1').addEventListener('input', () => updateInputValue('input1', 'value1'));
            document.getElementById('input2').addEventListener('input', () => updateInputValue('input2', 'value2'));
            document.getElementById('input3').addEventListener('input', () => updateInputValue('input3', 'value3'));
            document.getElementById('input4').addEventListener('input', () => updateInputValue('input4', 'value4'));
            
            // 初始预测
            predict();
        });
    </script>
</body>
</html>
